import json
from collections import OrderedDict
from datetime import date

from django.core.paginator import Paginator
from django.http import JsonResponse
from django.shortcuts import render

# Create your views here.
from django.views import View
from django_redis import get_redis_connection

from apps.contents.models import ContentCategory
from apps.goods.models import GoodsChannel, SKUImage, SKU, GoodsCategory, GoodsVisitCount
from utils.goods import get_categories, get_breadcrumb

# 搜索
from haystack.views import SearchView
from django.http import JsonResponse

from utils.viewmixin import LoginMixin


class MySearchView(SearchView):
    '''重写SearchView类'''

    def create_response(self):
        # 获取搜索结果
        context = self.get_context()
        data_list = []
        for sku in context['page'].object_list:
            data_list.append({
                'id': sku.object.id,
                'name': sku.object.name,
                'price': sku.object.price,
                'default_image_url': sku.object.default_image.url if sku.default_image else "",
                'searchkey': context.get('query'),
                'page_size': context['page'].paginator.num_pages,
                'count': context['page'].paginator.count
            })
        # 拼接参数, 返回
        return JsonResponse(data_list, safe=False)


class IndexView(View):

    def get(self, requests):
        categories = get_categories()

        # 广告数据
        contents = {}

        content_categories = ContentCategory.objects.all()

        for cat in content_categories:
            contents[cat.key] = cat.content_set.filter(status=True)

        context = {
            "categories": categories,
            "contents": contents
        }

        return render(requests, "index.html", context=context)


class ListView(View):

    def get(self, requests, category_id):
        # 获取参数

        page = requests.GET.get("page")
        page_size = requests.GET.get("page_size")
        ordering = requests.GET.get("ordering")
        # TODO 校验参数
        try:
            category = GoodsCategory.objects.get(id=category_id)
        except Exception as e:
            print(e)
            return JsonResponse({"code": 400, "errmsg": '分类查询失败'})

        # 面包屑导航数据

        breadcrumb = get_breadcrumb(category)

        # 分类商品的数据查询 （排序 分页)
        skus = SKU.objects.filter(category=category, is_launched=True).order_by(ordering)
        # 获取分页的paginator对象
        paginator = Paginator(skus, page_size)

        page_skus = paginator.page(page)

        sku_list = []

        for sku in page_skus:
            sku_list.append({
                "id": sku.id,
                "name": sku.name,
                "price": sku.price,
                "default_image_url": sku.default_image.url if  sku.default_image else "",
            })

        # 获取分页总页码
        count = paginator.num_pages

        return JsonResponse({"code": 0, "errmsg": 'ok', "breadcrumb": breadcrumb, "list": sku_list, "count": count})


# 热销商品

class HotGoodsView(View):

    def get(self, requests, category_id):
        try:
            skus = SKU.objects.filter(category_id=category_id, is_launched=True).order_by("-sales")
        except Exception as e:
            print(e)
            return JsonResponse({"code": 0, "errmsg": "查询错误"})

        hot_skus = []

        for sku in skus[:10]:
            hot_skus.append({
                "default_image_url": sku.default_image.url if sku.default_image else "",
                "id": sku.id,
                "name": sku.name,
                "price": sku.price,
            })

        return JsonResponse({"code": 0, "errmsg": 'ok', "hot_skus": hot_skus})


class DetailView(View):
    """商品详情页"""

    def get(self, request, sku_id):
        """提供商品详情页"""
        # 获取当前sku的信息
        try:
            sku = SKU.objects.get(id=sku_id)
        except SKU.DoesNotExist:
            return render(request, '404.html')

        # 查询商品频道分类
        categories = get_categories()
        # 查询面包屑导航
        breadcrumb = get_breadcrumb(sku.category)

        if not sku.default_image:
            sku.default_image= {"url":""}
        # 渲染页面
        context = {
            'categories': categories,
            'breadcrumb': breadcrumb,
            'sku': sku,
        }
        return render(request, 'detail.html', context)


# 埋点
class CategoryVisitCountView(View):
    def post(self, request, cat_id):
        # - 1接收分类id校验
        # 去数据库查询cat_id对应的分类是否存在GoodsCategory（自己完成）

        # - 2查看当天这个分类在数据库有没有记录
        today = date.today()
        try:
            goodsVisitCount = GoodsVisitCount.objects.get(category_id=cat_id, date=today)
        except:
            # - 3没有就创建新数据
            goodsVisitCount = GoodsVisitCount()

        try:
            # - 4有的话count + 1
            goodsVisitCount.count += 1
            goodsVisitCount.date = today
            goodsVisitCount.category_id = cat_id
            goodsVisitCount.save()
        except Exception as e:
            print(e)
            return JsonResponse({"code": 400, "errmsg": "失败"})

        # - 5返回响应
        return JsonResponse({"code": 0, "errmsg": "ok"})


# 用户浏览记录 redis
class UserBrowseHistory(LoginMixin, View):
    def post(self, request):
        user = request.user
        # 获取参数 sku_id
        json_data = json.loads(request.body)
        sku_id = json_data.get("sku_id")

        # todo 验证参数

        # 链接redis
        redis_conn = get_redis_connection('history')
        # 使用redis管道
        pl = redis_conn.pipeline()

        # 5 去重复
        # key             value
        # history_userId   [newsku_id, sku_id, sku_id, sku_id, sku_id, sku_id]
        pl.lrem("history_%s" % user.id, 0, sku_id)

        # 6 保存 到reids
        pl.lpush("history_%s" % user.id, sku_id)

        # 7 保存5条   01234
        pl.ltrim("history_%s" % user.id, 0, 4)
        pl.execute()  # 执行管道

        # 8 返回json
        return JsonResponse({"code": 0, "errmsg": "ok"})

    def get(self, requests):
        # 获取用户
        user = requests.user

        # 连接redis
        redis_conn = get_redis_connection('history')

        # 获取历史浏览记录 商品id
        sku_ids = redis_conn.lrange('history_%s' % user.id, 0, -1)

        skus = []

        for sku_id in sku_ids:
            sku = SKU.objects.get(id=sku_id)

            skus.append({
                "id": sku.id,
                "name": sku.name,
                "default_image_url": sku.default_image.url,
                'price': sku.price
            })

        return JsonResponse({'code': 0, 'errmsg': 'OK', 'skus': skus})
